import json
import time
import bcrypt
import threading
import random
import string
from functools import wraps
from rsa import RSA
import sys

sys.path.append("/home/sivan/0_0/gitee/Small_Tools/db_opr/python")
from mysql import MySQLPool

with open("/home/sivan/0_0/key_info/mysql_sivan.json", "r") as f:
    data = json.loads(f.read())
DB_CONFIG = {
    'host': '192.168.1.11',
    'port': 3310,
    'user': data["usr"],
    'password': data["pwd"],
    'database': data["db"],
    'charset': 'utf8',
    'pool_size': 10
}
db_pool = MySQLPool(**DB_CONFIG)


class PasswordHasher:
    @staticmethod
    def hash_password(password: str) -> str:
        """使用bcrypt哈希密码"""
        # 将密码转换为bytes
        password_bytes = password.encode('utf-8')

        # 生成盐并哈希密码
        # bcrypt会自动处理盐的生成和存储
        hashed = bcrypt.hashpw(password_bytes, bcrypt.gensalt())

        # 返回字符串形式的哈希值
        return hashed.decode('utf-8')

    @staticmethod
    def verify_password(plain_password: str, hashed_password: str) -> bool:
        """验证密码"""
        try:
            plain_bytes = plain_password.encode('utf-8')
            hashed_bytes = hashed_password.encode('utf-8')
            return bcrypt.checkpw(plain_bytes, hashed_bytes)
        except Exception:
            return False


# RSA密钥对管理
class RSAKeyManager:
    def __init__(self):
        self.rsa = RSA(key_size=1024)
        self.public_key_str, self.private_key_str = None, None
        self.key_expiry = 0
        self.key_ttl = 3600  # 1小时过期

    def generate_key_pair(self):
        """生成RSA密钥对"""
        # 生成密钥
        self.rsa.generate_keys()
        # 获取字符串形式的密钥
        self.public_key_str, self.private_key_str = self.rsa.keys_to_string()
        self.key_expiry = time.time() + self.key_ttl
        return self.public_key_str

    def get_public_key(self):
        """获取公钥，如果过期则重新生成"""
        if not self.public_key_str or time.time() > self.key_expiry:
            return self.generate_key_pair()
        return self.public_key_str

    def ensure_keys_exist(self):
        """确保公私钥都存在"""
        if not self.public_key_str or not self.private_key_str or time.time() > self.key_expiry:
            self.generate_key_pair()

    def decrypt(self, encrypted_data) -> str:
        """使用私钥解密数据"""
        # 确保公私钥存在
        self.ensure_keys_exist()
        return self.rsa.decrypt(encrypted_data)

    def encrypt(self, plaintext: str) -> str:
        """使用公钥加密数据"""
        # 确保公私钥存在
        self.ensure_keys_exist()
        return self.rsa.encrypt(plaintext)


class TokenManager:
    def __init__(self):
        self.token_pool = {}
        threading.Thread(target=self.polling_token, daemon=True).start()

    def get_token(self, user_info):
        characters = string.ascii_letters + string.digits
        token = ''.join(random.choice(characters) for _ in range(64))
        user_info["expiry"] = time.time() + 3600
        self.token_pool[token] = user_info
        return token

    def polling_token(self):
        while True:
            for token in list(self.token_pool.keys()):
                if time.time() > self.token_pool[token]["expiry"]:
                    self.token_pool.pop(token)
            time.sleep(60)

    def verify_token(self, token):
        if token in self.token_pool and time.time() <= self.token_pool[token]["expiry"]:
            return True
        return False


password_hasher = PasswordHasher()
# 初始化密钥管理器
key_manager = RSAKeyManager()
token_manager = TokenManager()


def token_required(func):
    """
    装饰器：检查user_data中的token是否存在且不为空字符串
    """

    @wraps(func)
    def wrapper(data, req):
        # 检查token是否存在且不为空字符串
        token = req.headers.get('token', None)
        if token is None or not token_manager.verify_token(token):
            return {"status": False, "error_message": "token校验失败"}
        return func(data, req)

    return wrapper
